package com.gitee.liuzhi.demo.mapstruct.converter;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
import org.mapstruct.factory.Mappers;

import java.time.LocalDateTime;
import java.util.Objects;

import static com.gitee.liuzhi.demo.mapstruct.MapStructMain.*;

/**
 * Created by 2022/4/21/0021
 *
 * @author LiuZhi
 * @version V1.0
 * @description: 用户转换映射器接口
 *
 * Mapper : 注解将接口标记为映射接口, 并允许MapStruct处理器在编译期间发挥作用
 * componentModel :
 *      default : 默认, mapstruct不使用任何组件类型, 可以通过Mappers.getMapper(Class)方式获取自动生成的实例对象
 *      cdi : the generated mapper is an application-scoped CDI bean and can be retrieved via @Inject
 *      spring : 生成的实现类上面会自动添加一个@Component注解，可以通过Spring的@Autowired方式进行注入
 *      jsr330 : 生成的实现类上会添加@javax.inject.Named 和@Singleton注解，可以通过 @Inject注解获取
 */
@Mapper(componentModel = "default")
public interface UserConverter {

    /**
     * 按照约定, 接口声明一个成员INSTANCE
     * 目的是让客户端可以访问Mapper接口的实现
     */
    UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);

    /**
     * model to dto
     *
     * @param user user
     * @return UserDTO
     */
    @Mappings({
            // 对于源对象和目标对象中具有不同字段名或不同类型的属性, 可以使用@Mapping注释来配置名称, 有expression和qualifiedByName两种方式实现
            @Mapping(target = "id", expression  = "java(com.gitee.liuzhi.demo.mapstruct.utils.ConverterUtils.singleToList(user.getId()))"),
            // source代表转换的源, target代表转换的目标
            @Mapping(target = "updateTime", source = "updateTime", qualifiedByName = "dateToStr")
    })
    UserDTO toDTO(User user);

    /**
     * model to vo
     *
     * @param user user
     * @return UserVO
     */
    UserVO toVO(User user);

    /**
     * localDateTime to localDateTimeStr
     * @param localDateTime localDateTime
     * @return localDateTimeStr
     */
    @Named("dateToStr")
    default String dateToStr(LocalDateTime localDateTime) {
        if(Objects.isNull(localDateTime)) {
            return null;
        }
        return localDateTime.toString();
    }

}
